package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.BspsMchntBaseInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsMchntBindInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsUserInfoMapper;
import cc.rengu.igas.bsps.common.dao.UserInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBaseInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBindInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsUserInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.UserInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.MchntBaseInfo;
import cc.rengu.igas.bsps.common.entity.MchntBindInfo;
import cc.rengu.igas.bsps.common.entity.UserInfo;
import cc.rengu.igas.bsps.common.enums.*;
import cc.rengu.igas.bsps.core.model.UserSessionInfo;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.request.CashierAddRequest;
import cc.rengu.igas.bsps.facade.response.CashierAddResponse;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.enums.PinTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.PasswordInfo;
import cc.rengu.oltp.service.realize.SafeKeyBoardService;
import cc.rengu.oltp.service.realize.impl.SafeKeyBoardServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhangxuran
 * @version 1.0
 * @date 2020/04/01
 */
public class CashierAddService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        CashierAddRequest cashierAddRequest = new CashierAddRequest();
        ConvertUtil.convertOutput(cashierAddRequest);
        return cashierAddRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        CashierAddRequest cashierAddRequest = (CashierAddRequest) request;
        CashierAddResponse cashierAddResponse = new CashierAddResponse();
        /*获取强求参数信息：法人行号、用户标识，商户号，收银员标识，收银员账号，收银员手机号，收银员姓名，昵称，角色，登录密码*/
        String instId = cashierAddRequest.getHeader().getInstId();
        String channelId = cashierAddRequest.getHeader().getChanlId();
        String userId = cashierAddRequest.getUserId();
        String mchntNo = cashierAddRequest.getMchntNo();
        String cashierUserId = cashierAddRequest.getCashierUserId();
        String cashierUserLoginId = cashierAddRequest.getCashierUserLoginId();
        String cashierMobileNo = cashierAddRequest.getCashierMobileNo();
        String cashierUserName = cashierAddRequest.getCashierUserName();
        String cashierUserNickName = cashierAddRequest.getCashierUserNickName();
        String cashierRole = cashierAddRequest.getCashierRole();
        String password = cashierAddRequest.getPassword();
        String confirmPassword = cashierAddRequest.getConfirmPassword();
        String cashierMchntNo = cashierAddRequest.getCashierMchntNo();
        String transInfoQueryAuth = cashierAddRequest.getTransInfoQueryAuth();

        /*必填性校验*/
        if (StringUtil.isEmptyOrNull(instId) || StringUtil.isEmptyOrNull(userId) || StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(cashierUserLoginId) ||
                StringUtil.isEmptyOrNull(cashierMobileNo) || StringUtil.isEmptyOrNull(cashierUserNickName) || StringUtil.isEmptyOrNull(cashierRole)
                || StringUtil.isEmptyOrNull(password) || StringUtil.isEmptyOrNull(cashierMchntNo)) {
            rglog.error("必填性校验失败！");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
        if (!BspsUserRoleTypeEnum.MCHNT_MANAGER.getRoleType().equals(cashierRole) && !BspsUserRoleTypeEnum.MCHNT_CASHIER.getRoleType().equals(cashierRole)) {
            rglog.error("用户角色枚举性校验失败！");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), "收银员角色信息错误");
        }

        UserInfoMapper userInfoMapper = new UserInfoMapperImpl();
        List<UserInfo> userInfoExistsList = userInfoMapper.selectBspsUserInfoByUserLoginId(instId, cashierUserLoginId);
        if (!CollectionUtils.isEmpty(userInfoExistsList) || "LOGINID".equals(cashierUserLoginId)) {
            rglog.error("用户名已存在");
            throw new BizException(RespCodeEnum.USER_ALREADY_REGISTER.getRespCode(), RespCodeEnum.USER_ALREADY_REGISTER.getRespDesc());
        }

        /*查询商户信息*/
        BspsMchntBaseInfoMapper mchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, cashierMchntNo);
        if (null == mchntBaseInfo) {
            rglog.error("查询商户基本信息失败,instId<{}>,cashierMchntNo<{}>", instId, cashierMchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        } else if (!MchntStatusEnum.NORMAL.getStatus().equals(mchntBaseInfo.getMchntStatus())){
            rglog.error("商户状态异常,无法新增收银员/店长,instId<{}>,cashierMchntNo<{}>", instId, cashierMchntNo);
            throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL_ADD_CASHIER_ERROR.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL_ADD_CASHIER_ERROR.getRespDesc());
        }

        //新增店长时判断商户类型及店长是否存在
        if (BspsUserRoleTypeEnum.MCHNT_MANAGER.getRoleType().equals(cashierRole)) {
            if (!"11".equals(mchntBaseInfo.getMchntType())) {
                rglog.error("商户非连锁商户门店，不能新增店长！");
                throw new BizException(RespCodeEnum.MCHNT_TYPE_ERROR.getRespCode(), "店长所属商户非连锁商户门店，无权新增店长");
            }
            BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
            List<MchntBindInfo> mchntBindInfoUserList = bspsMchntBindInfoMapper.selectBspsMchntBindInfoByMchntNoAndRoleType(instId, cashierMchntNo, cashierRole);
            if (!CollectionUtils.isEmpty(mchntBindInfoUserList)) {
                rglog.error("店长已存在！");
                throw new BizException(RespCodeEnum.MCHNT_MANAGER_EXIST_ERROR.getRespCode(), "门店已存在店长");
            }
        }

        SafeKeyBoardService safeKeyBoardService = new SafeKeyBoardServiceImpl();
        PasswordInfo passwordInfo = new PasswordInfo(cashierMchntNo, PinTypeEnum.MIXED, password);
        PasswordInfo confirmPasswordInfo = new PasswordInfo(cashierMchntNo, PinTypeEnum.MIXED, confirmPassword);
        if ("WECHAT".equals(channelId)) {
            password = safeKeyBoardService.encryptPassword(instId, "WECHAT", passwordInfo, null);
            confirmPassword = safeKeyBoardService.encryptPassword(instId, "WECHAT", confirmPasswordInfo, null);
        } else if ("PCWEB".equals(channelId)) {
            Header header = cashierAddRequest.getHeader();
            UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
            if (null == keySessionInfo) {
                rglog.error("sessino超时为空");
                throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
            }
            String randomString = keySessionInfo.getRandomString();
            keySessionInfo.setRandomString("");
            RedisUtil.onceSet(header.getSession(), JSONObject.toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);

            password = safeKeyBoardService.encryptPassword(instId, "WECHAT", passwordInfo, null);
            confirmPassword = safeKeyBoardService.encryptPassword(instId, "WECHAT", confirmPasswordInfo, null);
        }
        if (!password.equals(confirmPassword)) {
            rglog.error("密码不一致");
            throw new BizException(RespCodeEnum.PASSWORD_CHECK_ERROR.getRespCode(), RespCodeEnum.PASSWORD_CHECK_ERROR.getRespDesc());
        }

        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        /*生成唯一标识uuid*/
        String cashierUUID = RandomUtil.getUUID();
        int iReturnCode;
        /* 判断用户是新增用户，还是已有用户绑定新的商户收银员信息 */
        if (StringUtil.isEmptyOrNull(cashierUserId)) {
            /*用户表新增*/
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(cashierUUID);
            userInfo.setInstId(instId);
            userInfo.setLoginPassword(password);
            userInfo.setMobileNo(cashierMobileNo);
            userInfo.setUserStatus(UserStatusEnum.NOMAL.getStatus());
            userInfo.setUserName(cashierUserName);
            userInfo.setNickName(cashierUserNickName);
            userInfo.setUserLoginId(cashierUserLoginId);
            userInfo.setLoginAuthFlag("YYYY");
            userInfo.setOprId(userId);
            userInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
            iReturnCode = bspsUserInfoMapper.insertBspsUserInfo(userInfo);
            if (iReturnCode != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("登记用户信息表失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.REGISTER_USER_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_USER_INFO_ERROR.getRespDesc());
            }
        }
        /*商户绑定关系表实体*/
        MchntBindInfo mchntBindInfo = new MchntBindInfo();
        mchntBindInfo.setInstId(instId);
        mchntBindInfo.setMchntNo(cashierMchntNo);

        if (mchntBaseInfo.getMchntType().equals("10")) {
            mchntBindInfo.setChainMchntNo(mchntBaseInfo.getMchntNo());
        } else {
            mchntBindInfo.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
        }
        mchntBindInfo.setBindMchntType(mchntBaseInfo.getMchntType());
        mchntBindInfo.setBindNickName(cashierUserNickName);
        mchntBindInfo.setBindUserRole(cashierRole);
        mchntBindInfo.setBindUserId(cashierUUID);
        mchntBindInfo.setBindDate(DateUtil.getCurrentDate());
        mchntBindInfo.setBindTime(DateUtil.getCurrentTime());
        mchntBindInfo.setBindStatus(BindStatusEnum.BIND.getStatus());
        mchntBindInfo.setOprId(userId);
        mchntBindInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        Map<String, Object> reqMap = new HashMap<>();

        if (!StringUtil.isEmptyOrNull(transInfoQueryAuth) && transInfoQueryAuth.equals("01")) { //设置了查询订单权限
            reqMap.put("adminAuth", "Y");
        } else {
            reqMap.put("adminAuth", "N");
        }

        mchntBindInfo.setRemark1(JSONObject.toJSONString(reqMap));
        /*新增商户关系绑定表数据*/
        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        iReturnCode = bspsMchntBindInfoMapper.insertBspsMchntBindInfo(mchntBindInfo);
        if (iReturnCode != 0) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("登记商户绑定关系表失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.USER_BIND_MCHNT_ERROR.getRespCode(), RespCodeEnum.USER_BIND_MCHNT_ERROR.getRespDesc());
        }
        dbsUtil.dbsEndTransaction(true);
        /* 拼装响应结果 */
        BizResponse<CashierAddResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(cashierAddResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        CashierAddResponse cashierAddResponse = (CashierAddResponse) bizResponse.getResult();
        ConvertUtil.convertInput(cashierAddResponse);
    }
}
